package fortunata.servlets;

import fortunata.fswapps.vpoet.VPOETRequestData;
import fortunata.fswapps.vpoet.VPOETVisualizationRenderer;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;

import java.io.*;
import java.net.URLDecoder;

import org.apache.log4j.Logger;

public class VPoetRequestServlet extends HttpServlet {

    /**
     * Initilizing  (overwrites the default mathod provided by the Servlet interface). Reads values from web.xml
     *
     */
    protected static Logger log = Logger.getLogger( VPoetRequestServlet.class );
    protected String ontofilesDir = null; //This value is assigned in init(..)
    protected VPOETRequestData rpv = null;  //Asigned in each invocation
    static protected String fortunataBaseURL = null;

    /**
     * Initializes the servlet. It assigns the path to the onto files (defs and instances). Assumes that this servlet
     * is installed in the Fortunata web application
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        ontofilesDir = getServletContext().getRealPath("/");
        fortunataBaseURL = config.getInitParameter("FortunataBaseURL"); //This must be in the servlet init file (web.xml)
        //getServletContext().getContextPath() only exists for servlet spec 2.6 -> Tomcat 6
    }
    /**
     * Default constructor.
     */
    public VPoetRequestServlet(){

         //Moved to init(...)
    }

    /**
     * This methos is static, so it can be invoked by any external class. Useful, but risky...
     * @return  the URL or null if the servlet has not been initialized.
     */
    public static String getFortunataBaseURL(){
      //return getServletContext().getContextPath();  ONLY AVAILABLE ON spec 2.5 of servlets --> Tomcat 6 (requires Java 1.5)
      return fortunataBaseURL;
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
/*        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("GET Request. No Form Data Posted");*/
        doSomething(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse res)
            throws IOException, ServletException {
        doSomething(request, res);
    }

    public void doSomething(HttpServletRequest request, HttpServletResponse res)
            throws IOException, ServletException {
        rpv = new VPOETRequestData(request.getRequestURL().append("?").append(request.getQueryString()).toString());
        handleVPOETRequest (request, res, rpv);
    }

    /**
     * In this method the rpv is assigned
     * @param request
     * @param res
     * @param rpv
     * @throws IOException
     * @throws ServletException
     */
    public void handleVPOETRequest(HttpServletRequest request, HttpServletResponse res, VPOETRequestData rpv)
            throws IOException, ServletException {
        PrintWriter out = res.getWriter();
        rpv.valAction = request.getParameter(rpv.paramNameAction);
        String actionParam = rpv.valAction;
        VPOETVisualizationRenderer renderer = new VPOETVisualizationRenderer(ontofilesDir);
        // Handles ?action=renderInput&object=whatever&outformat=HTML&provider=whatever&source=whatever
        // Handles ?action=renderOutput&object=whatever&outformat=HTML&provider=whatever
        if (actionParam.equals(rpv.paramValueRenderInput) || actionParam.equals(rpv.paramValueRenderOutput)){
             rpv.valOntoElemID    = request.getParameter(rpv.paramNameOntoElemID);
             rpv.valOutFormat = request.getParameter(rpv.paramNameOutFormat);
             rpv.valProvider  = request.getParameter(rpv.paramNameProvider); //This parameter is optional
             if (rpv.valProvider == null){
                //We choose the best provider
                out.print ("'Best provider' funcionality not available now. Please, try later.");
                return;
             }
             rpv.valDesignID = request.getParameter(rpv.paramNameDesignID); //This parameter is optional
             String temp= request.getParameter(rpv.paramNameIndvID);
             rpv.valIndividualID = (temp != null && !temp.equals(""))? URLDecoder.decode(temp, "UTF-8"): null; //This parameter is optional
             //rpv.valIndividualID = request.getParameter(VPOETRequestData.paramNameIndvID); //This parameter is optional
             //Given a provider, an object, and an outputFormat...
             if (actionParam.equals(rpv.paramValueRenderInput)){ //action=renderInput
                  //rpv.valDesignType = VPOETRequestData.paramValueInput;
             }else{ //action=renderOutput
                  //rpv.valDesignType = VPOETRequestData.paramValueOutput;
                  if (request.getMethod().equals ("GET")){ //Needs source param
                      rpv.valSource = request.getParameter(rpv.paramNameSource);
                      if (rpv.valSource == null){
                          out.print ("parameter '" + rpv.paramNameSource +
                                         "' is mandatory in a HTTP GET request.");
                          return;
                      }
                  }else{ // POST doesn't need param "source"
                      //Get data from POST content
            //               BufferedReader bufred = request.getReader();
            //               String line;
            //               boolean canRead = true;
            //               while(canRead) {
            //                   line = bufred.readLine();
            //                   if (line == null){//It means end of buffer
            //                       canRead = false;
            //                   }else{
            //                      out.print (line);
            //                   }
            //               }
                  }
             } //Ends if action = renderInput/Output
             renderer.render(out, this.rpv);
        }else{ //Not valid action
           out.print ("action '"+ actionParam + "' is not valid.");
        }
    }
}
